#pragma once 
#include <iostream>
#include <string>
#include "InetAddr.hpp"
#include "Log.hpp"
#include <vector>
#include <memory>
#include <list>
#include "Mutex.hpp"
#include <algorithm>

using namespace MpthreayMutex;
using namespace LogModule;
class UserStrategy
{
public:
    UserStrategy() = default;
    virtual ~UserStrategy() {}
    virtual void SendMessage(int socketfd, std::string message) = 0; //抽象类
    virtual std::string Info() = 0; 
    virtual bool operator==(InetAddr& addr) = 0;
};

class User : public UserStrategy
{  
public:
    User(InetAddr& addr)
        :_net_addr(addr)
    {}

    void SendMessage(int socketfd, std::string message)
    {
        LOG(LogLevel::DEBUG) << message;
        ::sendto(socketfd,message.c_str(),message.size(),0,_net_addr.NetAddr(),_net_addr.Len());
    }

    std::string Info()
    {
        return _net_addr.netaddr();
    }

    virtual bool operator==(InetAddr& addr) {return _net_addr.IP()==addr.IP() && _net_addr.Port() == addr.Port();}
    ~User(){}
private:
    InetAddr _net_addr;
};

class UserManage
{
public:
    UserManage()
    {}

    void AddUser(InetAddr& in)
    {
        LockGround lock(_mtx);
        for (auto user_ptr:_user_set)
        {
            if (*user_ptr== in) 
            {
                std::cout << in.netaddr() << "已经存在" << std::endl;
                return;
            }
        }
        _user_set.emplace_back(std::make_shared<User>(in));
        LOG(LogLevel::DEBUG) << _user_set.back()->Info() << "添加成功";
        PrintUser();
    }

    void Route(int fd,std::string message)
    {
        LockGround lock(_mtx);
        for (auto _ptr:_user_set) 
        {
            _ptr->SendMessage(fd,message);
        }
    }

    void Delete(InetAddr& out)
    {
        LockGround lock(_mtx);
        auto pos = std::remove_if(_user_set.begin(),_user_set.end(),[&](std::shared_ptr<UserStrategy>& id){
            return *id==out;
        });
        _user_set.erase(pos,_user_set.end()); //一个迭代器区间范围
        PrintUser();
    }
    void PrintUser()
    {
        for (auto _ptr : _user_set)
        {
            LOG(LogLevel::INFO) <<  "在线用户" << _ptr->Info();
        }
    }
    ~UserManage(){}
private:
    std::list<std::shared_ptr<UserStrategy>> _user_set;
    Mutex _mtx;
};